package com.guddqs.monkey.shop.exception;

import com.guddqs.base.MapBean;
import com.guddqs.exception.CustomException;
import com.guddqs.exception.ErrorCodes;
import com.guddqs.monkey.shop.utils.MailService;
import org.jboss.logging.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Enumeration;
import java.util.regex.Pattern;

/**
 * @author wq
 * @date 2018/9/18
 */
@RestControllerAdvice
public class GlobalExceptionResolver {

    private static Pattern ignoreException = Pattern.compile("(Request method .* not supported|Connection refused|MethodArgumentTypeMismatchException)");

    @Value("${mail.error}")
    private String errorMail;
    @Value("${mail.dev}")
    private boolean dev;

    @Resource
    private MailService mailService;

    public static String getTrace(Throwable t) {
        StringWriter stringWriter = new StringWriter();
        PrintWriter writer = new PrintWriter(stringWriter);
        t.printStackTrace(writer);
        StringBuffer buffer = stringWriter.getBuffer();
        return buffer.toString().replaceAll("\n", "<br/>").replaceAll("\t", "&ensp;&ensp;&ensp;&ensp;");
    }

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public MapBean resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {

        Logger.getLogger(GlobalExceptionResolver.class).error(e.getMessage());

        CustomException customException;

        if (e instanceof CustomException) {
            customException = (CustomException) e;
            httpServletResponse.setStatus(customException.getStatusCode());
        } else {
            e.printStackTrace();
            httpServletResponse.setStatus(500);
            customException = new CustomException("系统开小差了");
            if (!dev && e.getMessage() != null && !ignoreException.matcher(e.toString()).find()) {
                String message = e.getMessage();
                if (e.getMessage().length() >= 30) {
                    if (e.getCause() != null && e.getCause().getMessage().length() <= 30) {
                        message = e.getCause().getMessage();
                    } else {
                        message = e.getMessage().substring(0, 10) + "...";
                    }
                }
                mailService.sendSimpleMail(errorMail.split(","), "[猴哥商城] 系统未知异常通知-" + message, "<pre>" + getReqInfo(httpServletRequest) + getTrace(e) + "</pre>");
            }
        }
        MapBean map = new MapBean();
        map.put("success", false);
        map.put("code", ErrorCodes.ERROR.getCode());
        map.put("result", customException.getMessage());
        map.put("errDesc", customException.getMessage());
        return map;
    }

    private String getReqInfo(HttpServletRequest request) {
        StringBuilder reqInfo = new StringBuilder("请求信息: <br/>IP : ").append(request.getHeader("X-Real-IP")).append(" <br/>URI: ").append(request.getRequestURI()).append("<br/>");
        Enumeration<String> names = request.getParameterNames();
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            String value = request.getParameter(name);
            reqInfo.append("&ensp; &ensp; 请求参数：").append(name).append(":").append(value).append("<br/>");
        }
        return reqInfo.toString() + "<br/>";
    }
}
